package com.bckj.fastboot.core.extra.mongo;

import com.bckj.fastboot.core.lang.model.PageResult;
import com.mongodb.BasicDBObject;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import org.bson.Document;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.math.BigInteger;
import java.util.List;

/**
 * MongoOps
 *
 * @author wfc
 **/
public class MongoOps extends MongoTemplate {

    public MongoOps(MongoDatabaseFactory mongoDbFactory) {
        super(mongoDbFactory);
    }

    public <R> PageResult<R> page(Pageable page, Query query, Class<R> entityClass) {
        return page(page, query, entityClass, getCollectionName(entityClass));
    }

    public <R>PageResult<R> page(Pageable page, Query query, Class<R> entityClass,
                                 String collectionName) {
        long count = count(query, entityClass, collectionName);
        // 构建查询
        query.with(page);
        List<R> list = find(query, entityClass, collectionName);
        return PageResult.<R>builder().items(list).total(BigInteger.valueOf(count)).build();
    }

    public MongoCursor<Document> findAll(String collectionName, Document projection, BasicDBObject sort, int limit) {
        MongoCollection<Document> coll = getCollection(collectionName);
        FindIterable<Document> f = coll.find();
        if (projection != null) {
            f.projection(projection);
        }
        if (sort != null) {
            f.sort(sort);
        }
        if (limit > 0) {
            f.limit(limit);
        } else {
            f.limit(1000);
        }
        return f.iterator();
    }

    public Query getIdQuery(Object id) {
        return Query.query(Criteria.where("_id").is(id));
    }

    public <R> boolean removeById(Object id, Class<R> entityClass) {
        return removeById(id, entityClass, getCollectionName(entityClass));
    }

    public <R> boolean removeById(Object id, Class<R> entityClass, String collectionName) {
        return remove(getIdQuery(id), entityClass, collectionName).getDeletedCount() > 0;
    }
}
